iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0

前言

昨天完成了 SubWise 後端部署到 Render,成功讓 Flask API 在雲端運行。不過目前的 SubWise 還只是一個「活著的 Backend」,使用者還沒有辦法透過 LINE 與它互動。

今天的目標是:建立 LINE Bot 與 Flask Backend 之間的 Webhook 通訊,讓 LINE 平台可以將使用者事件傳送到 SubWise。
今天完成後,SubWise 的架構會從「使用者 → (尚未連接)→ Flask Backend」,進化成:
LINE 使用者 → LINE Platform → Webhook URL → Render Flask Backend → /callback API → WebhookHandler 驗證


什麼是 Webhook?

Webhook 的概念跟傳統 API 不同:

  • 一般 API:使用者 → 主動呼叫 Server → 取得資料
  • Webhook:事件發生 → 第三方平台主動通知 Server → Server 處理事件

LINE Bot 的使用者傳送訊息後,LINE Platform 會主動 POST 到我們設定的 URL,這也是為什麼需要另外建立一個接收事件用的 Endpoint。


今日實作實錄:四步驟完成 Webhook 通訊

一、安裝 LINE Bot SDK

在專案目錄下啟動虛擬環境,安裝 LINE Messaging API SDK:

.\venv\Scripts\Activate.ps1
pip install line-bot-sdk
pip freeze > requirements.txt

更新 requirements.txt,讓 Render 部署時能自動安裝相同套件。

二、建立 LINE Webhook Endpoint

新增一支路由,作為接收 LINE 事件的入口:

@app.route("/callback", methods=["POST"])
def callback():
    body = request.get_data(as_text=True)
    return "OK"

三、加入 Webhook 驗證機制

為了確認請求真的來自 LINE 而不是其他來源,需要使用 Channel SecretX-Line-Signature 進行驗證:

from linebot.v3 import WebhookHandler
from linebot.v3.messaging import Configuration
from linebot.v3.exceptions import InvalidSignatureError

configuration = Configuration(
    access_token=os.getenv("LINE_CHANNEL_ACCESS_TOKEN")
)
handler = WebhookHandler(
    os.getenv("LINE_CHANNEL_SECRET")
)

接著修改 callback,加入簽章驗證邏輯:

@app.route("/callback", methods=["POST"])
def callback():
    signature = request.headers.get("X-Line-Signature")
    body = request.get_data(as_text=True)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        return "Invalid signature", 400

    return "OK"

現在 Flask 已經具備接收 LINE Webhook 的能力。

程式碼修改完成,且成功部署上線:
https://ithelp.ithome.com.tw/upload/images/20260805/201785270htvyNs4n8.png

四、設定 LINE Webhook URL

進入 LINE Developers Console,在 Messaging API 頁籤設定:

Webhook URL:https://subwise-line-bot.onrender.com/callback

按下 Verify,成功顯示 Success,代表 LINE 平台已經可以連線到 SubWise Backend。
https://ithelp.ithome.com.tw/upload/images/20260805/20178527fLHiVhtdlR.png
接著開啟 Use webhook,讓 LINE 事件正式送往我們的 Server。


今天踩到的兩個坑

1. NameError: name 'Configuration' is not defined

推送到 GitHub、Render 自動重新部署後第一次失敗,原因是少了 from linebot.v3.messaging import Configuration 這行 import,補上後重新 commit 即解決。

2. AttributeError: 'NoneType' object has no attribute 'encode'

第二次部署仍然失敗,原因是 Render 讀不到 LINE_CHANNEL_SECRET。本機能正常運作是因為有 .env 檔案,但 Render 並不會讀取本機的 .env。解決方式是改到 Render 的 Environment Variables 設定頁面,手動加入 LINE_CHANNEL_SECRETLINE_CHANNEL_ACCESS_TOKENGEMINI_API_KEY 三組金鑰,重新部署後成功。


實際測試 LINE → Flask 通訊

最後進行真實測試:用 LINE Bot 傳送「測試」訊息,查看 Render Logs,成功看到:
POST /callback HTTP/1.1" 200 -
https://ithelp.ithome.com.tw/upload/images/20260805/20178527IjbhTsgJ6z.png
(目前 Bot 還不會回覆訊息,因為訊息處理邏輯會在 Day 05 實作)

代表整條通訊鏈路成功建立:
LINE → Webhook → Render → Flask callback() → HTTP 200


明日預告

雲端後端跟 LINE 的通訊管道已經正式打通!明天 Day 05,我將開始實作 LINE Echo Bot,讓 SubWise 第一次真正回覆使用者訊息。我們明天見!


上一篇
[Day 03] 從本地走向雲端!Git 版本控制與 Flask API 成功部署 Render 實錄
系列文
AI 時代的輕量化開發:ChatGPT 打造 LINE 多模態記帳與續訂預警 Agent4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言